package com.zhihaoliang.moshi.biz.adapter

import com.squareup.moshi.*
import com.zhihaoliang.moshi.util.log
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.util.*


/**
 * @author 支豪亮
 * @date 2023/1/28 15:43
 */

fun customAdapterFactory(){
    val moshi = Moshi.Builder().add(SortedSetAdapterFactory()).build()
    val jsonAdapter: JsonAdapter<SortedSet<String>> = moshi.adapter(
        Types.newParameterizedType(
            SortedSet::class.java, String::class.java
        )
    )

    val model: TreeSet<String> = TreeSet()
    model.add("a")
    model.add("b")
    model.add("d")
    model.add("c")

    val json = jsonAdapter.toJson(model)
    log(json)
}

class SortedSetAdapter<T>(private val elementAdapter:JsonAdapter<T>): JsonAdapter<SortedSet<T>>() {
    override fun fromJson(reader: JsonReader): SortedSet<T> {
        val result: TreeSet<T> = TreeSet()
        reader.beginArray()
        while (reader.hasNext()) {
            elementAdapter.fromJson(reader)?.let { result.add(it) }
        }
        reader.endArray()
        return result
    }

    override fun toJson(writer: JsonWriter, value: SortedSet<T>?) {
        writer.beginArray()
        if(value != null) {
            for (element in value) {
                elementAdapter.toJson(writer, element)
            }
        }
        writer.endArray()
    }

}

class SortedSetAdapterFactory:JsonAdapter.Factory {
    override fun create(
        type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi
    ): JsonAdapter<*>? {
        if(annotations.isNotEmpty()) return null

        if(type !is ParameterizedType)return null

        if(type.rawType != SortedSet::class.java) return null

        val elementType = type.actualTypeArguments[0]
        val elementAdapter:JsonAdapter<Any?> = moshi.adapter(elementType)
        return SortedSetAdapter(elementAdapter).nullSafe()
    }

}